
#ifndef __STREAM_HPP__
#define __STREAM_HPP__

////////////////////////////////////////////////////////////////////////////////

#ifdef __STRICT_ANSI__
#undef __STRICT_ANSI__
#include <cstdio>
#define __STRICT_ANSI__
#else
#include <cstdio>
#endif

#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

////////////////////////////////////////////////////////////////////////////////

class stream {
public:
    virtual ~stream();

    operator bool() const;

    virtual FILE* get_file() const = 0;
};

////////////////////////////////////////////////////////////////////////////////

class istream : public virtual stream {
public:
    virtual istream& operator>>(std::string&);
    virtual istream& operator>>(std::vector<char>&);
};

////////////////////////////////////////////////////////////////////////////////

class ostream : public virtual stream {
public:
    template <typename T> ostream& operator<<(const T& t) {
        std::ostringstream os;
        os << t;
        return *this << os.str();
    }

    virtual ostream& operator<<(ostream& (*)(ostream&));
    virtual ostream& operator<<(const std::string&);
    virtual ostream& operator<<(const std::vector<char>&);

    static ostream& flush(ostream&);
};

////////////////////////////////////////////////////////////////////////////////

class iostream : public istream, public ostream {
};

////////////////////////////////////////////////////////////////////////////////

class stream_closed_exception : public std::exception {
};

////////////////////////////////////////////////////////////////////////////////

#endif
